﻿using System.Collections.Generic;

namespace Raven
{
    public class TriggerSystem
    {
        private LinkedList<Trigger<RavenBot>> _triggers = new LinkedList<Trigger<RavenBot>>();

        //this method iterates through all the triggers present in the system and
        //calls their Update method in order that their internal state can be
        //updated if necessary. It also removes any triggers from the system that
        //have their m_bRemoveFromGame field set to true.
        private void UpdateTriggers()
        {
            var curTrg = _triggers.First;
            while (curTrg != null)
            {
                //remove trigger if dead
                if (curTrg.Value.isToBeRemoved())
                {
                    _triggers.Remove(curTrg);
                }
                else
                {
                    //update this trigger
                    curTrg.Value.Update();
                }

                curTrg = curTrg.Next;
            }
        }

        //this method iterates through the container of entities passed as a
        //parameter and passes each one to the Try method of each trigger *provided*
        //the entity is alive and provided the entity is ready for a trigger update.
        void TryTriggers(IEnumerable<RavenBot> entities)
        {
            //test each entity against the triggers
            foreach (RavenBot curEnt in entities)
            {
                //an entity must be ready for its next trigger update and it must be 
                //alive before it is tested against each trigger.
                if (curEnt.isReadyForTriggerUpdate() && curEnt.isAlive())
                {
                    foreach (var curTrg in _triggers)
                    {
                        curTrg.Try(curEnt);
                    }
                }
            }
        }

        //this deletes any current triggers and empties the trigger list
        public void Clear()
        {
            _triggers.Clear();
        }

        public void Update(IEnumerable<RavenBot> entities)
        {
            UpdateTriggers();
            TryTriggers(entities);
        }

        //this is used to register triggers with the TriggerSystem (the TriggerSystem
        //will take care of tidying up memory used by a trigger)
        public void Register(Trigger<RavenBot> trigger)
        {
            _triggers.AddLast(trigger);
        }

        public LinkedList<Trigger<RavenBot>> GetTriggers()
        {
            return _triggers;
        }
    }
}